package org.example;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author yingyuwei
 * @version 1.0.0
 * @description TODO
 * @createTime 2021年03月06日 17:02:00
 */
public class SpinLock {

    public static void main(String[] args) throws InterruptedException {

        CustomerSpinLock customerSpinLock = new CustomerSpinLock();

        new Thread(() -> {
            customerSpinLock.lock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            customerSpinLock.unlock();
        }).start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            customerSpinLock.lock();
            customerSpinLock.unlock();
        }).start();

        new Thread(() -> {
            customerSpinLock.lock();
            customerSpinLock.unlock();
        }).start();

    }

    static class CustomerSpinLock {

        private AtomicReference<Thread> atomicReference = new AtomicReference<>();

        public void lock() {
            Thread thread = Thread.currentThread();
            System.out.println(thread.getName() + "   尝试获取锁");
            while (!atomicReference.compareAndSet(null, thread)) {
                System.out.println(thread.getName() + "   自旋中");
            }
            System.out.println(thread.getName() + "   获取锁");
        }

        public void unlock() {
            Thread thread = Thread.currentThread();
            atomicReference.compareAndSet(thread, null);
            System.out.println(thread.getName() + "   释放锁");
        }

    }
}
